//
//  BMSInitializer.m
//  WDBMS
//
//  Created by YeJary on 2025/5/13.
//

#import "BMSInitializer.h"
#import "BMSAPIService.h"
#import "BMSPrivate.h"
#import "BMSDeviceInfo.h"
#import "BMSOpMergeReporter.h"
#import "BMSPermissionManager.h"
#import "BMSAppInfoHelper.h"
#import "BMSDataPersistenceManager.h"
#import "BMSPrivate.h"
#import "BMSKeychain.h"
#import "WDGroMoreThinkingManager.h"
#import "WDGroMoreTrackManager.h"

@interface BMSInitializer ()

@property (nonatomic, assign) BOOL didAgreePrivacy;
@property (nonatomic, assign) BOOL didRealnameAuth;
@property (nonatomic, assign) BOOL idfaAuthorized;
//@property (nonatomic, assign) BOOL isTeenager;
@property (nonatomic, assign) BOOL didLogin;
@property (nonatomic, assign) BOOL shouldShowAntiAddictionTip;
@property (nonatomic, assign) BOOL shouldForceLogout;
@property (nonatomic, strong) NSArray<NSString *> *holidayList;
@property (nonatomic, strong) NSDate *serverNowDate;

@property (nonatomic,strong)BMSLoginResponseModel *loginModel;

@property (nonatomic,strong) BMSLaunchConfigModel *launchModel;

@property (nonatomic, copy) NSString *uuid;

@end

@implementation BMSInitializer

- (instancetype)init {
    self = [super init];
    if (self) {
        [self loadCachedState];//刷新缓存
    }
    return self;
}

+ (instancetype)shared {
    static BMSInitializer *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[BMSInitializer alloc] init];
        [instance loadCachedState];
        [instance restoreRealnameStatusOnAppLaunch];
#ifdef DEBUG
//        [instance clearCachedStateForTesting];
#endif
    });
    return instance;
}

- (void)loadCachedState {
    NSUserDefaults *ud = NSUserDefaults.standardUserDefaults;
    self.didAgreePrivacy = [ud boolForKey:kBMSKeyPrivacyAgreed];
    self.didRealnameAuth = [ud boolForKey:kBMSKeyRealnameAuth];
    self.isTeenager = [ud boolForKey:kBMSKeyIsTeenager];
    self.hasShownForcedRealnamePopup = [ud boolForKey:kBMSForcedRealname];

    NSArray *cachedHolidays = [ud objectForKey:kBMSKeyHolidayList];
    
    NSDate *cacheDate = [ud objectForKey:kBMSKeyHolidayCacheDate];
    if (cachedHolidays && [cacheDate isKindOfClass:NSDate.class]) {
        NSTimeInterval delta = [[NSDate date] timeIntervalSinceDate:cacheDate];
        if (delta < 24 * 60 * 60) {
            self.holidayList = cachedHolidays;
        }
    }
}

- (void)clearCachedStateForTesting {
    NSUserDefaults *ud = NSUserDefaults.standardUserDefaults;
    
    [ud removeObjectForKey:kBMSKeyPrivacyAgreed];
    [ud removeObjectForKey:kBMSKeyRealnameAuth];
    [ud removeObjectForKey:kBMSKeyIsTeenager];
    [ud removeObjectForKey:kBMSKeyHolidayList];
    [ud removeObjectForKey:kBMSKeyHolidayCacheDate];
    [ud removeObjectForKey:kBMSForcedRealname];
    [ud synchronize];
    
    self.didAgreePrivacy = NO;
    self.didRealnameAuth = NO;
    self.isTeenager = NO;
    self.holidayList = @[];
    
    NSLog(@"[BMS] 测试清除缓存已执行");
}

+ (void)startWithAppName:(NSString *)appName
                 version:(NSString *)version
                 channel:(NSString *)channel
              completion:(void(^)(void))completion {
    
    BMSInitializer *mgr = [BMSInitializer shared];
    dispatch_group_t group = dispatch_group_create();
    
    // 获取启动配置
    [self fetchLaunchConfigWithGroup:group
                             version:version
                             appName:appName];
    
    // 获取节假日信息（如果需要）
//    if (mgr.holidayList.count == 0) {
//
//    }
    [self fetchHolidayListWithGroup:group manager:mgr];
    
    // 检查IP屏蔽状态
    [self checkIPBlockStatusWithGroup:group
                              appName:appName
                              channel:channel
                              version:version
                              manager:mgr];
    
    // 所有任务完成后的回调
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        [mgr evaluateAntiAddictionPolicy];
        if (completion) {
            completion();
        }
    });
}

#pragma mark - 私有方法

+ (void)fetchLaunchConfigWithGroup:(dispatch_group_t)group
                           version:(NSString *)version
                           appName:(NSString *)appName {
    dispatch_group_enter(group);
    
    __block BOOL hasFetchedConfig = NO;

    [self retryTask:^(void(^taskCompletion)(BOOL success)) {
        [BMSAPIService fetchGameLaunchConfigWithVersion:version
                                                appName:appName
                                                success:^(id responseObject) {
            if (responseObject != nil) {
                hasFetchedConfig = YES;
                BOOL success = [self handleLaunchConfigResponse:responseObject];
                taskCompletion(success);
            } else {
                // 加载默认配置
                NSDictionary *responseData = [BMSAppInfoHelper loadDefaultBMSConfig];
                BMSLaunchConfigModel *model = [BMSLaunchConfigModel modelWithDictionary:responseData];
                [BMSInitializer shared].launchModel = model;
                [[BMSOpMergeReporter shared] setupWithLaunchConfig:model];

                [[BMSOpMergeReporter shared] addEvent:
                 [BMSOpMergeEventBuilder event_userOpWithAct:BMS_EVENT_BASE_JSON
                                                 description:BMS_WDS_FETCH_CONFIG]];
                BOOL success = [self handleLaunchConfigResponse:responseData];
                taskCompletion(success);
                NSLog(@"使用默认启动配置: %@", responseData);
            }
        } failure:^(NSError *error) {
            NSLog(@"获取启动配置失败: %@", error.localizedDescription);
            taskCompletion(NO);
        }];
    } maxRetries:2 completion:^{
        if (!hasFetchedConfig) {
            // 加载默认配置
            NSDictionary *responseData = [BMSAppInfoHelper loadDefaultBMSConfig];
            BMSLaunchConfigModel *model = [BMSLaunchConfigModel modelWithDictionary:responseData];
            [BMSInitializer shared].launchModel = model;
            [[BMSOpMergeReporter shared] setupWithLaunchConfig:model];

            [[BMSOpMergeReporter shared] addEvent:
             [BMSOpMergeEventBuilder event_userOpWithAct:BMS_EVENT_BASE_JSON
                                             description:BMS_WDS_FETCH_CONFIG]];

            NSLog(@"使用默认启动配置: %@", responseData);
        }
        dispatch_group_leave(group);
    }];
}

+ (void)fetchHolidayListWithGroup:(dispatch_group_t)group
                          manager:(BMSInitializer *)mgr {
    dispatch_group_enter(group);
    
    [self retryTask:^(void(^taskCompletion)(BOOL success)) {
        [BMSAPIService fetchOfficialHolidaysWithSuccess:^(id responseObject) {
            BOOL success = [self handleHolidayResponse:responseObject manager:mgr];
            taskCompletion(success);
        } failure:^(NSError *error) {
            NSLog(@"获取国家法定节假日失败: %@", error.localizedDescription);
            taskCompletion(NO);
        }];
    } maxRetries:2 completion:^{
        dispatch_group_leave(group);
    }];
}

+ (void)checkIPBlockStatusWithGroup:(dispatch_group_t)group
                            appName:(NSString *)appName
                            channel:(NSString *)channel
                            version:(NSString *)version
                            manager:(BMSInitializer *)mgr {
    dispatch_group_enter(group);
    
    [self retryTask:^(void(^taskCompletion)(BOOL success)) {
        [BMSAPIService checkIPBlockStatusWithAppName:appName
                                             channel:channel
                                             version:version
                                                  ip:nil
                                             success:^(NSDictionary *response) {
            BOOL success = [self handleIPBlockResponse:response manager:mgr];
            taskCompletion(success);
        } failure:^(NSError *error) {
            NSLog(@"获取IP屏蔽状态失败: %@", error.localizedDescription);
            taskCompletion(NO);
        }];
    } maxRetries:2 completion:^{
        dispatch_group_leave(group);
    }];
}

#pragma mark - 响应处理方法

+ (BOOL)handleLaunchConfigResponse:(id)responseObject {
    int code = [[responseObject objectForKey:@"code"] intValue];
    if (code == 0) {
        NSDictionary *responseData = responseObject[@"data"];
        BMSLaunchConfigModel *model = [BMSLaunchConfigModel modelWithDictionary:responseData];
        [BMSInitializer shared].launchModel = model;
        [[BMSOpMergeReporter shared] setupWithLaunchConfig:model];
        
        [[BMSOpMergeReporter shared] addEvent:[BMSOpMergeEventBuilder
            event_userOpWithAct:BMS_EVENT_BASE_JSON
                    description:BMS_WDS_FETCH_CONFIG]];
        
        NSLog(@"获取启动配置成功: %@", responseObject);
        return YES;
    } else {
        NSLog(@"获取启动配置失败，错误码: %d, 响应: %@", code, responseObject);
        return NO;
    }
}

+ (BOOL)handleHolidayResponse:(id)responseObject manager:(BMSInitializer *)mgr {
    int code = [[responseObject objectForKey:@"code"] intValue];
    if (code == 0) {
        BMSOfficialHolidayModel *model = [BMSOfficialHolidayModel modelWithRawArray:responseObject[@"data"]];
        mgr.holidayList = model.holidayList;
        [BMSAntiAddictionManager shared].holidaySet = model.holidayList;
        
        // 缓存到本地
        NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
        [ud setObject:model.holidayList forKey:kBMSKeyHolidayList];
        [ud setObject:[NSDate date] forKey:kBMSKeyHolidayCacheDate];
        [ud synchronize];
        
        NSLog(@"获取国家法定节假日成功: %@", responseObject);
        return YES;
    } else {
        NSLog(@"获取国家法定节假日失败，错误码: %d, 响应: %@", code, responseObject);
        return NO;
    }
}

+ (BOOL)handleIPBlockResponse:(NSDictionary *)response manager:(BMSInitializer *)mgr {
    int code = [[response objectForKey:@"code"] intValue];
    if (code == 0) {
        NSDictionary *data = response[@"data"];
        BMSIPBlockStatusModel *model = [BMSIPBlockStatusModel modelWithDictionary:data];
        mgr.serverNowDate = [NSDate date];
//        mgr.ipBlockModel = model; // 假设需要保存模型
        
        NSLog(@"获取IP屏蔽状态成功: %@", response);
        return YES;
    } else {
        NSLog(@"获取IP屏蔽状态失败，错误码: %d, 响应: %@", code, response);
        return NO;
    }
}

#pragma mark - 重试机制

+ (void)retryTask:(void(^)(void(^taskCompletion)(BOOL success)))task
       maxRetries:(NSInteger)maxRetries
       completion:(void(^)(void))completion {
    [self executeTask:task
          withAttempt:1
           maxRetries:maxRetries
           completion:completion];
}

+ (void)executeTask:(void(^)(void(^taskCompletion)(BOOL success)))task
        withAttempt:(NSInteger)attempt
         maxRetries:(NSInteger)maxRetries
         completion:(void(^)(void))completion {
    
    task(^(BOOL success) {
        if (!success && attempt < maxRetries) {
            // 失败且还有重试机会，延迟后重试
            NSTimeInterval delay = MIN(1 * attempt, 2.0); // 渐进式延迟，最大2秒
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
                                       (int64_t)(delay * NSEC_PER_SEC)),
                          dispatch_get_main_queue(), ^{
                [self executeTask:task
                      withAttempt:attempt + 1
                       maxRetries:maxRetries
                       completion:completion];
            });
        } else {
            // 成功或重试次数耗尽，任务结束
            if (completion) {
                completion();
            }
        }
    });
}

- (void)markPrivacyAgreed {
    self.didAgreePrivacy = YES;
    [NSUserDefaults.standardUserDefaults setBool:YES forKey:kBMSKeyPrivacyAgreed];
}

- (void)markRealnameVerified:(BOOL)isTeenager {
    self.didRealnameAuth = YES;
    self.isTeenager = isTeenager;
    NSUserDefaults *ud = NSUserDefaults.standardUserDefaults;
    [ud setBool:YES forKey:kBMSKeyRealnameAuth];
    [ud setBool:isTeenager forKey:kBMSKeyIsTeenager];
}

- (void)evaluateAntiAddictionPolicy {
    if (!self.isTeenager) {
        self.shouldShowAntiAddictionTip = NO;
        self.shouldForceLogout = NO;
        return;
    }

    NSDate *now = self.serverNowDate ?: [NSDate date];
    NSDateFormatter *df = [[NSDateFormatter alloc] init];
    df.dateFormat = @"yyyyMMdd";
    NSString *dateKey = [df stringFromDate:now];
    BOOL isHoliday = [self.holidayList containsObject:dateKey];

    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSInteger weekday = [calendar component:NSCalendarUnitWeekday fromDate:now];
    BOOL isWeekend = (weekday == 1 || weekday == 7 || weekday == 6);

    if (!(isHoliday || isWeekend)) {
        self.shouldShowAntiAddictionTip = YES;
        self.shouldForceLogout = YES;
        return;
    }

    NSDateComponents *components = [calendar components:NSCalendarUnitHour | NSCalendarUnitMinute fromDate:now];
    NSInteger hour = components.hour;
    NSInteger minute = components.minute;
    if (hour != 20 || (minute < 0 || minute >= 60)) {
        self.shouldShowAntiAddictionTip = YES;
        self.shouldForceLogout = YES;
    } else {
        self.shouldShowAntiAddictionTip = NO;
        self.shouldForceLogout = NO;
    }
}

- (void)handlePrivacyAgreedAndLoginWithCompletion:(void(^)(BOOL loginSuccess))completion {
    // 标记已同意隐私
    self.didAgreePrivacy = YES;

    // 获取 IDFA、IDFV
    [[BMSPermissionManager sharedManager] fetchIdentifiersWithCompletion:^(NSString * _Nullable idfa, NSString *idfv) {
        self.idfaAuthorized = (idfa.length > 0);

        // 更新设备信息
        [[BMSDeviceInfo shared] updateWithIDFA:idfa idfv:idfv];

        // 请求登录（可用缓存 UUID 或新建）
        [BMSAPIService loginWithOpenId:[BMSAppInfoHelper getOpenId]
                               appName:[BMSAppInfoHelper bmsAppNameForInfoPlistFile]
                             platform:@"ios"
                                 idfa:idfa
                                 idfv:idfv
                                 imei:nil
                                 oaid:nil
                                 adid:nil
                                  mac:nil
                               serial:nil
                              success:^(NSDictionary *response) {
            NSLog(@"登录完成: %@", response);
            [[BMSOpMergeReporter shared]addEvent:[BMSOpMergeEventBuilder event_userActionWithAct:BMS_EVENT_USER_LOGIN description:BMS_WDS_ACTIVE_STATISTICS tab1:@"" tab2:@"" tab3:@"" tabN:@{}]];
            [WDGroMoreTrackManager track:BMS_EVENT_ACTIVE params:@{BMS_PARAM_WDS:BMS_WDS_ACTIVATE} dType:BMS_DTYPE_USER_OPERATION desc:BMS_WDS_ACTIVATE options:[WDGroMoreTrackManager trackOptionsOnlySendBMS]];

            int code = [response[@"code"]intValue];;
            if(code == 0) {
                NSDictionary *data = response[@"data"];
                BMSLoginResponseModel *model = [BMSLoginResponseModel modelWithDictionary:data];
                self.loginModel = model;
                self.loginModel = [[BMSLoginResponseModel alloc] init];
                self.uuid = model.uuid;
                self.didLogin = YES;
                [self handleUserSourceInfo];
                if (completion) completion(YES);
            } else {
                NSLog(@"登录失败\n%@",response);
                self.didLogin = NO;
                self.uuid = [BMSKeychain WDKeychainGetUUID];
                if (completion) completion(NO);
            }
            
        } failure:^(NSError *error) {
            self.didLogin = NO;
            self.uuid = [BMSKeychain WDKeychainGetUUID];
            if (completion) completion(NO);
            NSLog(@"登录失败: %@", error.localizedDescription);
        }];
    }];
}

- (void)handlePrivacyAgreedAndLogin {
    [[BMSInitializer shared] markPrivacyAgreed];

    NSString *userId = [BMSKeychain WDKeychainGetUUID];
    NSString *idfa = [BMSDeviceInfo shared].idfa;
    NSString *idfv = [BMSDeviceInfo shared].idfv;
    
    [BMSInitializer shared].appName = [BMSAppInfoHelper bmsAppNameForInfoPlistFile];


    [BMSAPIService loginWithOpenId:userId
                          appName:[BMSInitializer shared].appName
                         platform:@"ios"
                             idfa:idfa
                             idfv:idfv
                             imei:nil
                             oaid:nil
                             adid:nil
                              mac:nil
                           serial:nil
                          success:^(NSDictionary *response) {
        NSLog(@"登录完成: %@", response);
        
        [[BMSOpMergeReporter shared]addEvent:[BMSOpMergeEventBuilder event_userActionWithAct:BMS_EVENT_USER_LOGIN description:BMS_WDS_ACTIVE_STATISTICS tab1:@"" tab2:@"" tab3:@"" tabN:@{}]];
        
        
        int code = [response[@"code"]intValue];;
        if(code == 0) {
            NSDictionary *data = response[@"data"];
            BMSLoginResponseModel *model = [BMSLoginResponseModel modelWithDictionary:data];
            self.loginModel = model;
            self.loginModel = [[BMSLoginResponseModel alloc] init];
            self.uuid = model.uuid;
            self.didLogin = YES;
            [self handleUserSourceInfo];
        } else {
            NSLog(@"登录失败\n%@",response);
            self.didLogin = NO;
            self.uuid = [BMSKeychain WDKeychainGetUUID];
        }
        
    } failure:^(NSError *error) {
        self.didLogin = NO;
        self.uuid = [BMSKeychain WDKeychainGetUUID];
        NSLog(@"登录失败: %@", error.localizedDescription);
    }];
}

- (void)handleUserSourceInfo {
    NSString *idfa = [BMSDeviceInfo shared].idfa;
    NSString *idfv = [BMSDeviceInfo shared].idfv;
    [BMSAPIService fetchUserSourceWithAppName:[BMSInitializer shared].appName
                                      version:[BMSInitializer shared].version
                                      channel:[BMSInitializer shared].channel
                                         uuid:self.uuid
                                         idfa:idfa
                                         idfv:idfv
                                         imei:nil
                                         oaid:nil
                                   android_id:nil
                                      success:^(NSDictionary *sourceData) {
        int code = [[sourceData objectForKey:@"code"]intValue];
        if (code == 0){
            NSLog(@"✅ 用户来源：%@", sourceData);
            
            NSDictionary *data = sourceData[@"data"];
            BMSUserSourceModel *model = [BMSUserSourceModel modelWithDictionary:data];
            
            NSMutableDictionary *params = [[NSMutableDictionary alloc]init];
            [params setObject:model.source forKey:@"source"];
            [params setObject:model.planId forKey:@"plan_id"];
            [params setObject:@(model.activeTime) forKeyedSubscript:@"active_time"];
            [params setObject:model.activeDate forKey:@"active_date"];
            [params setObject:model.aidId forKey:@"aid_id"];
            [params setObject:model.campaignId forKey:@"campaign_id"];
            
            [[WDGroMoreThinkingManager manager]uploadUserSourceOnceWithAttributes:params];
            
        } else {
            NSLog(@"获取用户来源失败\n %@",sourceData);
        }
        
    } failure:^(NSError *error) {
        NSLog(@"❌ 获取用户来源失败：%@", error.localizedDescription);
    }];
}

- (void)restoreRealnameStatusOnAppLaunch {
    if ([self hasCompletedRealnameFromStorage]) {
        self.didRealnameAuth = YES;
        self.isTeenager = [self isTeenagerFromStorage];
        
        NSLog(@"🔄 恢复实名状态：已认证=%@, 未成年=%@",
              self.didRealnameAuth ? @"是" : @"否",
              self.isTeenager ? @"是" : @"否");
              
        // 如果是未成年人，重新启动防沉迷检查
        if (self.isTeenager) {
            // 这里可以重新初始化防沉迷相关逻辑
            // [BMSAntiAddictionManager restartAntiAddictionCheck];
        }
    }
}

#pragma mark - 新增方法：持久化存储
- (void)saveTeenagerStatusToPersistentStorage:(BOOL)isTeenager {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setBool:YES forKey:@"BMS_HasCompletedRealname"]; // 标记已完成实名
    [defaults setBool:isTeenager forKey:@"BMS_IsTeenager"];    // 存储是否未成年
    [defaults synchronize];
    
    NSLog(@"💾 持久化存储：实名状态=%@, 未成年=%@", @"已完成", isTeenager ? @"是" : @"否");
}

- (BOOL)hasCompletedRealnameFromStorage {
    return [[NSUserDefaults standardUserDefaults] boolForKey:@"BMS_HasCompletedRealname"];
}

- (BOOL)isTeenagerFromStorage {
    return [[NSUserDefaults standardUserDefaults] boolForKey:@"BMS_IsTeenager"];
}

#pragma mark ------- lazy load --------

- (BMSLoginResponseModel *)loginModel {
    if (!_loginModel) {
        _loginModel = [[BMSLoginResponseModel alloc] init];
    }
    return _loginModel;
}

- (BMSLaunchConfigModel *)launchModel {
    if(!_launchModel){
        _launchModel = [[BMSLaunchConfigModel alloc]init];
    }
    return _launchModel;
}

@end
